package com.css.common.core.utils;

import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
/*import org.apache.http.ssl.SSLContexts;*/
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.util.List;
import java.util.Map;


/**
 * HttpServletUtil
 *
 <dependency>
 <groupId>org.apache.httpcomponents</groupId>
 <artifactId>httpclient</artifactId>
 <version>4.5.3</version>
 </dependency>
 <dependency>
 <groupId>org.apache.httpcomponents</groupId>
 <artifactId>httpmime</artifactId>
 <version>4.5.3</version>
 </dependency>
 *
 * @author wangliang
 * @Date: 2015-1-30 下午2:07:55
 */
public class HttpClientUtil {
//    private static CloseableHttpClient httpclient;
//    private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();

    private static CloseableHttpClient httpClient;

    // 采用静态代码块，初始化超时时间配置，再根据配置生成默认httpClient对象
    static {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000).build();
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
    }

    /**
     * Post:访问数据库并返回数据字符串
     *
     * @param params
     *            向服务器端传的参数
     * @param url
     * @return String 数据字符串
     * @throws Exception
     */
    //表单方式
    public static String doPost(List<NameValuePair> params, String url) throws Exception {
        String result = null;
        httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
//        //设置请求和传输超时时间
//        httpPost.setConfig(requestConfig);
        CloseableHttpResponse httpResp = httpClient.execute(httpPost);
        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
//                System.out.println("状态码:" + statusCode);
//                System.out.println("请求成功!");
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            } else {
//                System.out.println("状态码:"
//                        + httpResp.getStatusLine().getStatusCode());
//                System.out.println("HttpPost方式请求失败!");
            }
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }

    //json方式
    public static String doPost_json(String jsonParam, String url) throws Exception {
        String result = null;
        httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);

        StringEntity entity = new StringEntity(jsonParam,"utf-8");//解决中文乱码问题
        entity.setContentEncoding("UTF-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        //设置请求和传输超时时间
//        httpPost.setConfig(requestConfig);
        CloseableHttpResponse httpResp = httpClient.execute(httpPost);
        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
//                System.out.println("状态码:" + statusCode);
//                System.out.println("请求成功!");
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            } else {
//                System.out.println("状态码:"
//                        + httpResp.getStatusLine().getStatusCode());
//                System.out.println("HttpPost方式请求失败!");
            }
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }



    /**
     * Get:访问数据库并返回数据字符串
     *
     * @param url
     * @return String 数据字符串
     * @throws Exception
     */
    public static String doGet(String url) throws Exception{
        String result = null;
        httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        //设置请求和传输超时时间
//        httpGet.setConfig(requestConfig);
        CloseableHttpResponse httpResp = httpClient.execute(httpGet);
        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
//                System.out.println("状态码:" + statusCode);
//                System.out.println("请求成功!");
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            } else {
//                System.out.println("状态码:"
//                        + httpResp.getStatusLine().getStatusCode());
//                System.out.println("HttpGet方式请求失败!");
            }
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }

    /**
     * Get:访问数据库并返回数据字符串
     *
     * @param url
     * @return String 数据字符串
     * @throws Exception
     */
    public static String doGet_json(String jsonParam, String url) throws Exception{
        String result = null;
        httpClient = HttpClients.createDefault();//等价于 HttpClientBuilder.create().build();

        RequestBuilder requestBuilder = RequestBuilder.get(url);
        requestBuilder.addHeader("Content-type", "application/json");
        StringEntity jsonBody = new StringEntity(jsonParam, ContentType.APPLICATION_JSON);
        requestBuilder.setEntity(jsonBody);
        HttpUriRequest httpRequest = requestBuilder.build();
        //设置请求和传输超时时间
//        httpRequest.setConfig(requestConfig);
        CloseableHttpResponse httpResp = httpClient.execute(httpRequest);

        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
//                System.out.println("状态码:" + statusCode);
//                System.out.println("请求成功!");
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            } else {
//                System.out.println("状态码:"
//                        + httpResp.getStatusLine().getStatusCode());
//                System.out.println("HttpGet方式请求失败!");
            }
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }

    /**
     * 发送 http put 请求，参数以原生字符串进行提交
     * @param stringJson
     * @param url
     * @param headers
     * @return
     */
    public static String doPut(String stringJson, String url, Map<String,String> headers) throws Exception{

        String result = null;
        httpClient = HttpClients.createDefault();

        HttpPut httpput = new HttpPut(url);

        //设置header
        httpput.setHeader("Content-type", "application/json");
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpput.setHeader(entry.getKey(),entry.getValue());
            }
        }

        StringEntity jsonBody = new StringEntity(stringJson, ContentType.APPLICATION_JSON);//或 UTF-8
        httpput.setEntity(jsonBody);
        //设置请求和传输超时时间
//        httpRequest.setConfig(requestConfig);
        CloseableHttpResponse httpResp = httpClient.execute(httpput);

        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
//                System.out.println("状态码:" + statusCode);
//                System.out.println("请求成功!");
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            } else {
//                System.out.println("状态码:"
//                        + httpResp.getStatusLine().getStatusCode());
//                System.out.println("HttpGet方式请求失败!");
            }
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }


    /**
     * 发送 http Delete 请求，参数以原生字符串进行提交
     * @param url
     * @param headers
     * @return
     */
    public static String doDelete(String url, Map<String,String> headers) throws Exception{

        String result = null;
        httpClient = HttpClients.createDefault();

        HttpDelete httpDelete = new HttpDelete(url);

        //设置header
        httpDelete.setHeader("Content-type", "application/json");
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpDelete.setHeader(entry.getKey(),entry.getValue());
            }
        }
        //设置请求和传输超时时间
//        httpRequest.setConfig(requestConfig);
        CloseableHttpResponse httpResp = httpClient.execute(httpDelete);

        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
//                System.out.println("状态码:" + statusCode);
//                System.out.println("请求成功!");
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            } else {
//                System.out.println("状态码:"
//                        + httpResp.getStatusLine().getStatusCode());
//                System.out.println("HttpGet方式请求失败!");
            }
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }


    /**
     *   Https TODO----------未测试
     * @param certPath
     * @param url
     * @return
     * @throws Exception
     */
    /*public static String doGetByHttps(String certPath, String certPassWord, String url) throws Exception{
        String result = null;
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());//默认是jks
        FileInputStream instream = new FileInputStream(new File(certPath));
        try {
            // 加载keyStore d:\\tomcat.keystore
            trustStore.load(instream, certPassWord.toCharArray());
        } catch (CertificateException e) {
            throw new RuntimeException("doGetByHttps.trustStore.load发生异常", e);
        } finally {
            instream.close();
        }
        // 相信自己的CA和所有自签名的证书
        SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();

        // 解决httpClient发送https错误的问题
        SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(SSLContexts.custom().loadTrustMaterial(
                null,
                new TrustSelfSignedStrategy()).build(),
                NoopHostnameVerifier.INSTANCE
        );
        httpClient = HttpClients.custom().setSSLSocketFactory(scsf).build();

        // 创建http请求(get方式)
        HttpGet httpget = new HttpGet(url);
        //System.out.println("executing request" + httpget.getRequestLine());
        CloseableHttpResponse httpResp = httpClient.execute(httpget);

        try {
            int statusCode = httpResp.getStatusLine().getStatusCode();
            // 判断是够请求成功
            if (statusCode == HttpStatus.SC_OK) {
                // 获取返回的数据
                result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            throw new RuntimeException("doGetByHttps发生异常", e);
        } finally {
            httpResp.close();
            httpClient.close();
        }
        return result;
    }*/

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("-------");
        try {
//            String jsonStr_cj = "{\n" +
//                    "  \"settings\": {\n" +
//                    "    \"number_of_shards\": 1,\n" +
//                    "    \"number_of_replicas\": 1\n" +
//                    "  },\n" +
//                    "  \"mappings\": {\n" +
//                    "    \"properties\": {\n" +
//                    "      \"name\": {\n" +
//                    "        \"type\": \"text\"\n" +
//                    "      },\n" +
//                    "      \"age\": {\n" +
//                    "        \"type\": \"integer\"\n" +
//                    "      }\n" +
//                    "    }\n" +
//                    "  }\n" +
//                    "}";

//            String jsonStr_add = "{\n" +
//                    "  \"name\":\"王五\",\n" +
//                    "  \"age\":45\n" +
//                    "}";

//            String jsonStr_cx = "{\n" +
//                    "  \"query\": {\n" +
//                    "  \"bool\": {\n" +
//                    "     \"must\": [\n" +
//                    "       { \"term\": { \"name\": \"中\" } },\n" +
//                    "       { \"term\": { \"name\": \"与\" } },\n" +
//                    "       { \"term\": { \"name\": \"软\" } }\n" +
//                    "     ]\n" +
//                    "  }\n" +
//                    " },\n" +
//                    "    \"from\": 0,\n" +
//                    "    \"size\": 20\n" +
//                    "}";


            String jsonStr_cx = "{\n" +
                    "  \"query\": {\n" +
                    "    \"match_all\": {}\n" +
                    "  },\n" +
                    "  \"from\": 0,\n" +
                    "  \"size\": 2\n" +
                    "}";

            //创建索引
//            String s = HttpClientUtil.doPut(jsonStr_cj, "http://127.0.0.1:9200/user", null);
            //保存索引文档（新增/更新）
//            String s = HttpClientUtil.doPost_json(jsonStr_add, "http://127.0.0.1:9200/user/_doc/3");
            //删除索引文档
//            String s = HttpClientUtil.doDelete("http://127.0.0.1:9200/user/_doc/3",null);
            //查询索引文档
            String s = HttpClientUtil.doGet_json(jsonStr_cx, "http://127.0.0.1:9200/org/_search");
//            String s = HttpClientUtil.doGet_json(jsonStr_cx, "http://10.23.12.68:9200/mx_ztyp_ssy_nsrxx_2/_search");

            //调用结果(JSON字符串)
            System.out.println("---s----"+s);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}